import { ValidationAcceptor } from "langium";
import { Decl, VarDef, VariableLVal, isConstDef, isFuncFParam, isVarDef } from "./generated/ast.js";

export class DeclValidator {
    // 检查变量是否在块内重定义
    checkUniqueDef(constDecl: Decl, accept: ValidationAcceptor): void {
        const reported = new Set<string>();
        constDecl.defs.forEach(d => {
            if (reported.has(d.name)) {
                accept('error', `无法重新声明块范围变量 '${d.name}'。`, { node: d, property: 'name' });
            }
            reported.add(d.name);
        });
    }

    // 数组越界悬浮提示
    hoverTipsArray(arr: VarDef, accept: ValidationAcceptor): void {
        if (arr.index[0])//是一个数组才能取值
        {
            const length = (arr.index[0] as { value: string }).value;// 获取数组长度
            const lengthInt = parseInt(length, 10); // 将字符串解析为整数，第二个参数 10 表示使用十进制解析
            if (arr.Init[0].manyInit.length > lengthInt) {
                accept("error", `数组 ${arr.name} 的初始化元素数量超过了数组大小。`, { node: arr, property: undefined });
            }
        }
    }

    // 左值悬停提示
    hoverTipsLval(lval: VariableLVal, accept: ValidationAcceptor): void {
        let ref = lval.value.ref;
        if (isFuncFParam(ref)) {
            // 函数形参悬停提示
            accept("hint", `(参数) ${lval.value.$refText}: ${ref?.btype}。`, { node: lval, property: undefined });
        } else if (isConstDef(ref)) {
            // 常量
            accept("hint", `${ref.$cstNode?.container?.text}`, { node: lval, property: undefined });
        } else if (isVarDef(ref)) {
            // 普通变量
            accept("hint", `${ref.$cstNode?.container?.text}`, { node: lval, property: undefined });
        }
    }

    // 检查未定义的变量
    checkVariableDeclared(lval: VariableLVal, accept: ValidationAcceptor): void {
        if (!lval.value.ref) {
            accept('error', `使用了未定义的变量 '${lval.value.$refText}'。`, { node: lval, property: 'value' });
        }
    }
}